﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Controls;
using QDP.Platform.ObjService;
namespace QDP.Platform.Silverlight
{
    /// <summary>表示一个基础组件对象。</summary>
    [WidgetMeta(Category=NParams.CategoryCommon, Key = NParams.Autorun
        , Desc = "表示应用在平台加载完成自动运行.", DefaultValue = NParams.False)]
    [WidgetMeta(Category=NParams.CategoryAdvanced, Key = NParams.Args
        , Desc = "表示应用实例化时传入的参数.")]
    [WidgetMeta(Category=NParams.CategoryAdvanced, Key = NParams.ScriptableObject
        , Desc = "表示应用注册JavaScript对象名称.")]
    [WidgetMeta(Category=NParams.CategoryAdvanced, Key = NParams.IgnoreError
        , Desc = "表示忽略该应用触发的未处理异常.")]
    [WidgetMeta(Category = NParams.CategoryCommon, Key = NParams.AutoHideTopic
        , Desc = "表示应用启动后是否隐藏专题工具栏.", DefaultValue = NParams.False)]
    [WidgetMeta(Category = NParams.CategoryCommon, Key = NParams.AutoShowTopic
        , Desc = "表示应用关闭后是否展开专题工具栏.", DefaultValue = NParams.False)]
    [WidgetMeta(Category = NParams.CategoryLayout, Key = NParams.ColumnSpan
        , Desc = "表示应用自定义磁贴所占列数,整型.", DefaultValue = 1)]
    [WidgetMeta(Category = NParams.CategoryLayout, Key = NParams.RowSpan
        , Desc = "表示应用自定义磁贴所占列数,整型,最大为2.", DefaultValue = 1)]
    [WidgetMeta(Category = NParams.CategoryStyle, Key = NParams.CustomTile
        , Desc = "表示应用自定义磁贴样式.")]
    [WidgetMeta(Category = NParams.CategoryAdvanced, Key = NParams.ExclusionGroup
        , Desc = "表示应用的互斥分组，若设置了之后则同分组内有应用启动时,关闭其他已启动的应用.")]
    [WidgetMeta(Category = NParams.CategoryAdvanced, Key = NParams.PremiseTipIsNone
        , Desc = "表示应用前置条件不成立时提示的消息.")]
    [WidgetMeta(Category = NParams.CategoryAdvanced, Key = NParams.ShowPremise
        , Desc = "表示应用启动的前置条件,该值为一个应用的CODE.")]
    [WidgetMeta(Category = NParams.CategoryLayout, Key = NParams.ShowInTile
        , Desc = "是否在磁贴中显示.", DefaultValue = true)]
    public abstract class PartElement : ObservableObject
    {
        const string Property_Desc = "Desc";
        const string Property_TileTemplate = "TileTemplate";
        const string Property_IsActived = "IsActived";
        const string Property_IsContented = "IsContented";
        const string Property_WidgetContent = "WidgetContent";
        const string Property_WidgetParent = "WidgetParent";
        const string Property_IsShowed = "IsShowed";
        const string Property_Config = "Config";

        private bool _IsShowed;
        private bool _IsActived;
        private bool _IsContented;
        private Control _WidgetContent;
        private Panel _WidgetParent;
        private NavigationBase _Desc;
        private ControlTemplate _TileTemplate;
        private Dictionary<string, string> _Config;
        /// <summary>
        /// 以默认参数构造一个基础组件对象。
        /// </summary>
        /// <remarks></remarks>
        public PartElement()
        {
            IsShowed = false;
            IsActived = false;
            IsContented = true;
            _Config = new Dictionary<string, string>();
        }
        /// <summary>
        /// 获取或设置组件的自描述信息。
        /// </summary>
        public NavigationBase Desc
        {
            get { return _Desc; }
            set
            {
                if (_Desc != value)
                {
                    _Desc = value;
                    Notify(Property_Desc);
                }
            }
        }
        /// <summary>
        /// 获取或设置组件自定义磁贴模板，若为空则使用默认模板。
        /// </summary>
        public ControlTemplate TileTemplate
        {
            get { return _TileTemplate; }
            set
            {
                if (_TileTemplate != value)
                {
                    _TileTemplate = value;
                    Notify(Property_TileTemplate);
                }
            }
        }
        /// <summary>
        /// 获取或设置当前对象是否满足后续应用启动前提。
        /// </summary>
        public bool IsContented
        {
            get { return _IsContented; }
            set
            {
                if (_IsContented != value)
                {
                    _IsContented = value;
                    Notify(Property_IsContented);
                }
            }
        }

        #region 关于组件激活及反激活
        private void ChangeZIndex()
        {
            try
            {
                if (WidgetParent == null) return;
                var indexs = from i in WidgetParent.Children select Canvas.GetZIndex(i);
                if (indexs.Count() == 0) return;
                int index = indexs.Max();
                Canvas.SetZIndex(WidgetContent, index + 1);
            }
            catch (Exception ex)
            {
                this.ShowMessage(ex.Message,ex.ToString());
            }
        }
        /// <summary>
        /// 激活窗口，使其显示在同级别的顶端
        /// </summary>
        public virtual void Active()
        {
            this.ChangeZIndex();
            IsActived = true;
            Tasker.Active(this);
        }
        /// <summary>
        /// 反激活窗口，使其显示在同级别的底端
        /// </summary>
        public virtual void Unactive()
        {
            IsActived = false;
        }
        /// <summary>
        /// 获取或设置一个值，该值指定组件对象是否激活显示。
        /// </summary>
        public bool IsActived
        {
            get { return _IsActived; }
            set
            {
                if (_IsActived != value)
                {
                    _IsActived = value;
                    Notify(Property_IsActived);
                }
            }
        }
        #endregion //#region 关于组件激活及反激活

        #region 关于组件打开关闭
        /// <summary>
        /// 获取或设置组件的内容。
        /// </summary>
        public Control WidgetContent
        {
            get { return _WidgetContent; }
            set
            {
                if (_WidgetContent != value)
                {
                    _WidgetContent = value;
                    Notify(Property_WidgetContent);
                }
            }
        }
        /// <summary>
        /// 获取或设置展示组件的父级对象。
        /// </summary>
        public Panel WidgetParent
        {
            get { return _WidgetParent; }
            set
            {
                if (_WidgetParent != value)
                {
                    _WidgetParent = value;
                    Notify(Property_WidgetParent);
                }
            }
        }
        /// <summary>
        /// 打开 QDP.Platform.Silverlight.PartElement 对象。
        /// </summary>
        public virtual void Show()
        {
            if (CheckShowPremise() == false)
            {
                IsShowed = false;
                return; 
            }
            IsShowed = true;            // 标识窗口已经展开
            this.Active();              // 激活
            this.ExclusionWidget();     // 处理组件互斥操作。
            if (WidgetContent == null) return;
            if (WidgetParent == null || WidgetParent.Children.Contains(WidgetContent)) return;
            WidgetParent.Children.Add(WidgetContent);
            //  当AutoHideTopic参数不为false时均执行
            if ( this.GetConfigValue(NParams.AutoHideTopic).ToLower() == NParams.True)
            {
                Q.ToolbarManager.Hide();
            }
        }
        private bool CheckShowPremise()
        {
            // 获取应用启动的前提，当前提不成立时，打开失败；
            string showPremise = this.GetConfigValue(NParams.ShowPremise);
            if (string.IsNullOrEmpty(showPremise)) return true;
            string[] premises = showPremise.Split(',');
            bool canShow = true;
            string errmsg = string.Empty;
            foreach (var premise in premises)
            {
                var widget = Q.WidgetManager.GetExistedWidget(premise);
                if (widget == null)
                {
                    canShow = false;
                    errmsg = "未发现前置应用或前置应用不存在，应用打开失败！";
                    break;
                }
                if (widget.PartElement == null)
                {
                    canShow = false;
                    errmsg = "前置应用[" + widget.Navigation.Caption + "]未启动，应用打开失败！";
                    break;
                }
                if (widget.PartElement.IsContented == false)
                {
                    canShow = false;
                    errmsg = "[" + widget.Navigation.Caption + "]未满足启动条件，应用打开失败！";
                    break;
                }
            }
            // 不满足启动的前提条件，退出启动
            if (canShow == false)
            {
                string mode = this.GetConfigValue(NParams.PremiseTipIsNone);
                if (mode.ToLower() == NParams.True)
                    this.ShowMessage(errmsg);
                return false;
            }
            else
            {
                return true;
            }
        }
        /// <summary>
        /// 根据传入的值获取该Key在参数列表中的定义；
        /// </summary>
        /// <param name="Key">要取值的键；</param>
        /// <returns></returns>
        public string GetConfigValue(string Key)
        {
            if (Config.ContainsKey(Key))
                return Config[Key];
            else
                return string.Empty;
        }
        /// <summary>
        /// 关闭 QDP.Platform.Silverlight.PartElement 对象。
        /// </summary>
        public virtual void Close()
        {
            this.Hide();
            var v = from i in Q.WidgetManager.Widgets
                    where i.Navigation.Code == this._Desc.Code
                    select i;

            if (v.Count() == 1)
            {
                var element = v.First();
                this.WidgetContent.Name = string.Empty;
                element.PartElement = null;
            }
        }
        /// <summary>
        /// 隐藏 QDP.Platform.Silverlight.PartElement 对象
        /// </summary>
        public virtual void Hide()
        {
            IsShowed = false;                // 表示窗口已经关闭
            if (this.IsActived)              // 如果窗口在未激活状态关闭时，不触发激活其他项。
            {
                this.Unactive();
                Tasker.ActiveLast();
            }
            Tasker.Remove(this);

            if (WidgetContent == null) return;
            if (WidgetParent == null || WidgetParent.Children.Contains(WidgetContent) == false) return;
            WidgetParent.Children.Remove(WidgetContent);
            //  当AutoShowTopic参数不为false时均执行
            if (this.GetConfigValue(NParams.AutoShowTopic).ToLower() == NParams.True)
            {
                Q.ToolbarManager.Show();
            }
        }
        /// <summary>
        /// 获取或设置当前QDP.Platform.Silverlight.PartElement 对象是否打开。
        /// </summary>
        public bool IsShowed
        {
            get { return _IsShowed; }
            set
            {
                if (_IsShowed != value)
                {
                    _IsShowed = value;
                    Notify( Property_IsShowed);
                }
            }
        }
        #endregion // #region 关于组件打开关闭

        #region 关于配置
        /// <summary>
        /// 获取QDP.Platform.Silverlight.PartElement 对象配置内容。
        /// </summary>
        public Dictionary<string, string> Config
        {
            get { return _Config; }
            set
            {
                if (_Config != value)
                {
                    _Config = value;
                    Notify( Property_Config);
                }
            }
        }
        #endregion //#region 关于配置

        #region 关于组件互斥
        /// <summary>
        /// 
        /// </summary>
        protected void ExclusionWidget()
        {
            // 处理组件互斥操作。
            if (Config.ContainsKey(NParams.ExclusionGroup))
            {
                Tasker.AddExclusion(Config[NParams.ExclusionGroup], this.GetType().FullName, this);
                Tasker.ResumeExclusion(this.GetType().FullName);
            }
        }
        #endregion //#region 关于组件互斥
    }
}